﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Office.Interop.Excel;

using Excel = Microsoft.Office.Interop.Excel;
using Office = Microsoft.Office.Core;
using System.Drawing;


namespace Zen4SyncReport.Report
{
    /// <summary>
    /// Provides methods allowing easy styling of Excel Cells and Range.
    /// The styles proposed by the methods of this class rely on the "Settings" file of the project.
    /// </summary>
    public class ExcelStylizer
    {
        #region - Methods -

        /// <summary>
        /// Merge the cells of the given range.
        /// </summary>
        /// <param name="worksheet">Worksheet to operate on.</param>
        /// <param name="startRow">Start row of the range.</param>
        /// <param name="startColumn">Start column of the range.</param>
        /// <param name="endRow">End row of the range.</param>
        /// <param name="endColumn">End column of the range.</param>
        public void MergeCells(Worksheet worksheet, int startRow, int startColumn, int endRow, int endColumn)
        {
            GetRange(worksheet, startRow, startColumn, endRow, endColumn).Merge();
        }

        /// <summary>
        /// Applies the "Title 1" style to the given range.
        /// Cells of the range are merged by this method.
        /// </summary>
        /// <param name="worksheet">Worksheet to operate on.</param>
        /// <param name="startRow">Start row of the range.</param>
        /// <param name="startColumn">Start column of the range.</param>
        /// <param name="endRow">End row of the range.</param>
        /// <param name="endColumn">End column of the range.</param>
        public void ApplyTitle1Style(Worksheet worksheet, int startRow, int startColumn, int endRow, int endColumn)
        {
            Excel.Range range = GetRange(worksheet, startRow, startColumn, endRow, endColumn);
            range.Interior.Color = Properties.Settings.Default.Style_Title1_BackgroundColor;
            range.Font.Bold = Properties.Settings.Default.Style_Title1_FontBold;
            range.HorizontalAlignment = Properties.Settings.Default.Style_Title1_HAlignement;
            range.Font.Size = Properties.Settings.Default.Style_Title1_FontSize;
            range.Merge();
        }

        /// <summary>
        /// Applies the "Title 2" style to the given range.
        /// Cells of the range are merged by this method.
        /// </summary>
        /// <param name="worksheet">Worksheet to operate on.</param>
        /// <param name="startRow">Start row of the range.</param>
        /// <param name="startColumn">Start column of the range.</param>
        /// <param name="endRow">End row of the range.</param>
        /// <param name="endColumn">End column of the range.</param>
        public void ApplyTitle2Style(Worksheet worksheet, int startRow, int startColumn, int endRow, int endColumn)
        {
            Excel.Range range = GetRange(worksheet, startRow, startColumn, endRow, endColumn);
            range.Interior.Color = Properties.Settings.Default.Style_Title2_BackgroundColor;
            range.Font.Bold = Properties.Settings.Default.Style_Title2_FontBold;
            range.HorizontalAlignment = Properties.Settings.Default.Style_Title2_HAlignement;
            range.Font.Size = Properties.Settings.Default.Style_Title2_FontSize;
            range.Merge();
        }

        /// <summary>
        /// Applies the "Title 3" style to the given range.
        /// Cells of the range are merged by this method.
        /// </summary>
        /// <param name="worksheet">Worksheet to operate on.</param>
        /// <param name="startRow">Start row of the range.</param>
        /// <param name="startColumn">Start column of the range.</param>
        /// <param name="endRow">End row of the range.</param>
        /// <param name="endColumn">End column of the range.</param>
        public void ApplyTitle3Style(Worksheet worksheet, int startRow, int startColumn, int endRow, int endColumn)
        {
            Excel.Range range = GetRange(worksheet, startRow, startColumn, endRow, endColumn);
            range.Interior.Color = Properties.Settings.Default.Style_Title3_BackgroundColor;
            range.Font.Italic= Properties.Settings.Default.Style_Title3_FontItalic;
            range.HorizontalAlignment = Properties.Settings.Default.Style_Title3_HAlignement;
            range.Font.Size = Properties.Settings.Default.Style_Title3_FontSize;
            range.Merge();
        }

        /// <summary>
        /// Applies the "Table Header" style to the given range.
        /// Cells of the range are not merged by this method.
        /// </summary>
        /// <param name="worksheet">Worksheet to operate on.</param>
        /// <param name="startRow">Start row of the range.</param>
        /// <param name="startColumn">Start column of the range.</param>
        /// <param name="endRow">End row of the range.</param>
        /// <param name="endColumn">End column of the range.</param>
        public void ApplyTableHeaderStyle(Worksheet worksheet, int startRow, int startColumn, int endRow, int endColumn)
        {
            Excel.Range range = GetRange(worksheet, startRow, startColumn, endRow, endColumn);
            range.Font.Italic = Properties.Settings.Default.Style_TableHeader_FontItalic;
            range.Font.Bold = Properties.Settings.Default.Style_TableHeader_FontBold;
            range.Font.Size = Properties.Settings.Default.Style_TableHeader_FontSize;
            range.HorizontalAlignment = Properties.Settings.Default.Style_TableHeader_HAlignement;
        }

        /// <summary>
        /// Applies alternatively the given Colors to the lines of the given range.
        /// color1 is always the color applied to the first line.
        /// If a border color is given, it's applied to each line on top/bottom/right/left borders.
        /// </summary>
        /// <param name="worksheet">Worksheet to operate on.</param>
        /// <param name="startRow">Start row of the range.</param>
        /// <param name="startColumn">Start column of the range.</param>
        /// <param name="endRow">End row of the range.</param>
        /// <param name="endColumn">End column of the range.</param>
        /// <param name="color1">The first Color to apply.</param>
        /// <param name="color2">The second Color to apply.</param>
        /// <param name="borderColor">Color for line borders. null for no color.</param>
        public void ApplyDoubleLineColor(Worksheet worksheet, int startRow, int startColumn, int endRow, int endColumn, Color color1, Color color2, Color borderColor)
        {
            int colorNumber = 0;

            for (int i = startRow; i <= endRow; i++)
            {
                Excel.Range line = GetRange(worksheet, i, startColumn, i, endColumn);
                line.Interior.Color = (colorNumber % 2 == 0 ? color1 : color2);
                if (borderColor != null)
                {
                    /* NOTE : Framework error in the XlBordersIndex enum
                     * Correct values: 
                     * xlEdgeLeft = 1,
                     * xlEdgeRight = 2,
                     * xlEdgeTop = 3,
                     * xlEdgeBottom = 4,
                     * xlDiagonalTop et XlDiagonalDown : enum OK
                     */
                    line.Borders[(Excel.XlBordersIndex)1].Color = borderColor;
                    line.Borders[(Excel.XlBordersIndex)2].Color = borderColor;
                    line.Borders[(Excel.XlBordersIndex)3].Color = borderColor;
                    line.Borders[(Excel.XlBordersIndex)4].Color = borderColor;
                }
                
                colorNumber++;
            }
        }

        /// <summary>
        /// Applies the given Color as the Background Color to the given range.
        /// </summary>
        /// <param name="worksheet">Worksheet to operate on.</param>
        /// <param name="startRow">Start row of the range.</param>
        /// <param name="startColumn">Start column of the range.</param>
        /// <param name="endRow">End row of the range.</param>
        /// <param name="endColumn">End column of the range.</param>
        /// <param name="backgroundColor">The Background Color to apply.</param>
        public void ApplyBackgroundColor(Worksheet worksheet, int startRow, int startColumn, int endRow, int endColumn, Color backgroundColor)
        {
            Excel.Range range = GetRange(worksheet, startRow, startColumn, endRow, endColumn);
            range.Interior.Color = backgroundColor;
        }

        /// <summary>
        /// Gets a range from the given coordonates.
        /// </summary>
        // <param name="worksheet">Worksheet to operate on.</param>
        /// <param name="startRow">Start row of the range.</param>
        /// <param name="startColumn">Start column of the range.</param>
        /// <param name="endRow">End row of the range.</param>
        /// <param name="endColumn">End column of the range.</param>
        /// <returns>Range containing the Cells of the given coordonates.</returns>
        public Excel.Range GetRange(Worksheet worksheet, int startRow, int startColumn, int endRow, int endColumn)
        {
            Excel.Range startCell = worksheet.Cells[startRow, startColumn];
            Excel.Range endCell = worksheet.Cells[endRow, endColumn];
            return worksheet.get_Range(startCell, endCell);
        }

        /// <summary>
        /// Auto adjusts the width of the columns of the given range.
        /// </summary>
        /// <param name="worksheet">Worksheet to operate on.</param>
        /// <param name="startRow">Start row of the range.</param>
        /// <param name="startColumn">Start column of the range.</param>
        /// <param name="endRow">End row of the range.</param>
        /// <param name="endColumn">End column of the range.</param>
        public void AutoFitColumns(Worksheet worksheet, int startRow, int startColumn, int endRow, int endColumn)
        {
            Excel.Range range = GetRange(worksheet, startRow, startColumn, endRow, endColumn);
            range.EntireColumn.AutoFit();
        }

        #endregion - Methods -
    }
}
